package mobilesmil.activity.composer;

import java.util.regex.Pattern;

import mobilesmil.activity.R;
import mobilesmil.data.*;
import mobilesmil.data.SmilTextResource;
import mobilesmil.utils.FormValidationUtils;
import mobilesmil.view.RegionPositioningView;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;

/**
 * Provides access to a drag 'n drop interface via {@link RegionPositioningView} for positioning and resizing the {@link SmilRegion}
 * of the currently editing {@link SmilResource}.
 * @author Ryan Ware
 *
 */
public class RegionPositioningActivity extends Activity {
	
	private static final byte MENU_DONE = 0;
	private static final byte MENU_CANCEL = 1;
	private static final byte MENU_EDIT_REGION = 2;
	
	private static final byte DIALOG_EDIT_REGION_ID = 0;
	private static final byte DIALOG_FORM_INVALID_ID = 1;
	
	private SmilResource mEditingResource = ComposerActivity.getEditingResource();
	private RegionPositioningView mView;
	private View mRegionPropsView;
	private EditText mEditHeight, mEditWidth, mEditTop, mEditLeft;
	
	private int mRegionHeight = 100;
	private int mRegionWidth = 100;
	private int mRegionTop = 0;
	private int mRegionLeft = 0;
	private Rect mEditingRegionRect;
	private boolean mRegionUpdatedByDialog = false;
	private String mDialogInvalidFormTitle = "";
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
		mRegionPropsView = inflater.inflate(R.layout.properties_form_region, null);
        
        mView = new RegionPositioningView(this);
        setContentView(mView);
        
        mEditHeight = (EditText)mRegionPropsView.findViewById(R.id.editRegionHeight);
        mEditWidth = (EditText)mRegionPropsView.findViewById(R.id.editRegionWidth);
        mEditTop = (EditText)mRegionPropsView.findViewById(R.id.editRegionTop);
        mEditLeft = (EditText)mRegionPropsView.findViewById(R.id.editRegionLeft);
    }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENU_EDIT_REGION, 0, "Edit Region").setIcon(android.R.drawable.ic_menu_edit);
		menu.add(0, MENU_DONE, 1, "Done").setIcon(android.R.drawable.ic_menu_set_as);
		menu.add(0, MENU_CANCEL, 2, "Cancel").setIcon(android.R.drawable.ic_menu_close_clear_cancel);
		return true;
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		AlertDialog dialog = null;
	    switch(id) 
	    {
		    case DIALOG_EDIT_REGION_ID:
		    	dialog = createRegionPropsFormDialog();
		    	break;
		    case DIALOG_FORM_INVALID_ID:
		    	dialog = FormValidationUtils.createInvalidFormDialog(this);
		    	dialog.setTitle(mDialogInvalidFormTitle);
		    	break;
	    }
	    return dialog;
	}
	
	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		super.onPrepareDialog(id, dialog);
		switch(id) 
	    {
		    case DIALOG_EDIT_REGION_ID:
		    	dialog = createRegionPropsFormDialog();
		    	break;
	    }
	}
	
	/**
	 * Creates the {@link AlertDialog} that allows the user to directly enter the {@link SmilRegion}'s
	 * left, top, height, and width parameters.
	 * @return {@link AlertDialog} the region editing dialog box
	 */
	private AlertDialog createRegionPropsFormDialog() {
		AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
		dialogBuilder.setView(mRegionPropsView);
		dialogBuilder.setTitle("Edit Region Properties");
        
        if(!ComposerActivity.isCreatingNewResource() && mView.getRegionRect() != null) 
        { // fill the forms of the dialog box with the pre-existing parameters
        	mEditingRegionRect = mView.getRegionRect().getRect();
        	mEditHeight.setText(String.valueOf(mEditingRegionRect.height()));
        	mEditWidth.setText(String.valueOf(mEditingRegionRect.width()));
        	mEditTop.setText(String.valueOf(mEditingRegionRect.top));
        	mEditLeft.setText(String.valueOf(mEditingRegionRect.left));
        }
		
    	dialogBuilder.setPositiveButton("Done", 
    			new DialogInterface.OnClickListener() {
    				public void onClick(DialogInterface dialog, int whichButton) {
    					if(fieldsAreValid()) { // update all of the parameters
	    					mRegionHeight = Integer.parseInt(mEditHeight.getText().toString());
	    			        mRegionWidth = Integer.parseInt(mEditWidth.getText().toString());
	    			        mRegionTop = Integer.parseInt(mEditTop.getText().toString());
	    			        mRegionLeft = Integer.parseInt(mEditLeft.getText().toString());
	    			        mRegionUpdatedByDialog = true;
	    			        return;
    					} else {
    						showDialog(DIALOG_FORM_INVALID_ID);
    					}
    			    }
    	});
    	dialogBuilder.setNegativeButton("Cancel", 
    			new DialogInterface.OnClickListener() {
    				public void onClick(DialogInterface dialog, int whichButton) {
    					return;
    			    }
    	});
    	return dialogBuilder.create();
	}
	
	/**
	 * Ensures user input fields contain valid values.
	 * @return true if all user input fields are valid, false if any are not
	 */
	private boolean fieldsAreValid() {
		String height = mEditHeight.getText().toString();
		String width = mEditWidth.getText().toString();
		String top = mEditTop.getText().toString();
		String left = mEditLeft.getText().toString();
		String integerRegex = FormValidationUtils.INTEGER_REGEX;
		
		if(Pattern.matches(integerRegex, height) && Pattern.matches(integerRegex, width)
				&& Pattern.matches(integerRegex, top) && Pattern.matches(integerRegex, left)) {
			return true;
		}
		else {
			mDialogInvalidFormTitle = "Region properties must be positive integer values.";
			return false;
		}
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId())
		{
		case MENU_DONE:
			saveResource();
			finish();
			break;
			
		case MENU_CANCEL:
			finish();
			break;
			
		case MENU_EDIT_REGION:
			showDialog(DIALOG_EDIT_REGION_ID);
			break;
		}
		return true;
	}
	
	/**
	 * Sets the {@link SmilRegion} of the editing {@link SmilResource} to match the parameters entered by
	 * the user. Also updates {@link SmilTextResource} for correct text wrapping.
	 */
	private void saveResource() {
		mEditingResource.getSmilRegion().setRect(mView.getRegionRect().getRect());
		if(mEditingResource.getType() == SmilResource.TYPE_TEXT)
			((SmilTextResource)mEditingResource).updateText();
	}
	
	@Override
	public void onBackPressed() {
		saveResource();
		finish();
	}

	public int getRegionHeight() {
		return mRegionHeight;
	}

	public void setRegionHeight(int regionHeight) {
		this.mRegionHeight = regionHeight;
	}

	public int getRegionWidth() {
		return mRegionWidth;
	}

	public void setRegionWidth(int regionWidth) {
		this.mRegionWidth = regionWidth;
	}

	public int getRegionTop() {
		return mRegionTop;
	}

	public void setRegionTop(int regionTop) {
		this.mRegionTop = regionTop;
	}

	public int getRegionLeft() {
		return mRegionLeft;
	}

	public void setRegionLeft(int regionLeft) {
		this.mRegionLeft = regionLeft;
	}

	public boolean isRegionUpdatedByDialog() {
		return mRegionUpdatedByDialog;
	}

	public void setRegionUpdatedByDialog(boolean regionUpdatedByDialog) {
		this.mRegionUpdatedByDialog = regionUpdatedByDialog;
	}

}
